package com.example.springboot_sdse_air.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot_sdse_air.entity.SystemPdf;
import com.example.springboot_sdse_air.mapper.SystemPdfMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.List;

/**
 * 功能：SystemPdf服务类
 * 作者：王彬 202200111149
 * 日期：2025-06-13 22:15
 */
@Service
public class SystemPdfService extends ServiceImpl<SystemPdfMapper, SystemPdf> {

    @Resource
    SystemPdfMapper systemPdfMapper;
    
    @Value("${ip:localhost}")
    String ip;

    @Value("${server.port}")
    String port;
    
    private static final String ROOT_PATH = System.getProperty("user.dir") + File.separator + "files" + File.separator + "SystemPdf";
    
    /**
     * 分页模糊查询
     */
    public Page<SystemPdf> pageQuery(Integer current, Integer size, String name) {
        Page<SystemPdf> page = new Page<>(current, size);
        
        LambdaQueryWrapper<SystemPdf> wrapper = new LambdaQueryWrapper<>();
        
        // 文件名模糊查询
        if (StrUtil.isNotBlank(name)) {
            wrapper.like(SystemPdf::getName, name);
        }
        
        // 按ID降序排列
        wrapper.orderByDesc(SystemPdf::getSpid);
        
        return this.page(page, wrapper);
    }
    
    /**
     * 单个删除
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Integer id) {
        // 先查询文件信息
        SystemPdf systemPdf = this.getById(id);
        if (systemPdf == null) {
            return false;
        }
        
        // 删除物理文件
        deletePhysicalFile(systemPdf.getDownloadUrl());
        
        // 删除数据库记录
        return this.removeById(id);
    }
    
    /**
     * 批量删除
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDelete(List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        
        // 查询所有要删除的文件信息
        List<SystemPdf> systemPdfs = this.listByIds(ids);
        
        // 删除物理文件
        for (SystemPdf systemPdf : systemPdfs) {
            deletePhysicalFile(systemPdf.getDownloadUrl());
        }
        
        // 删除数据库记录
        return this.removeByIds(ids);
    }
    
    /**
     * 批量上传
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpload(List<MultipartFile> files) {
        if (files == null || files.isEmpty()) {
            return false;
        }
        
        for (MultipartFile file : files) {
            if (!file.isEmpty()) {
                uploadSingleFile(file);
            }
        }
        
        return true;
    }
    
    /**
     * 上传单个文件
     */
    private void uploadSingleFile(MultipartFile file) {
        try {
            String originalFilename = file.getOriginalFilename();  // 文件的原始名称
            
            String mainName = FileUtil.mainName(originalFilename);  // 文件名
            String extName = FileUtil.extName(originalFilename);  // 文件拓展名
            String save_path = ROOT_PATH + File.separator + mainName; // 真正的存储父文件夹
            String parent_folder_name;
            
            if (!FileUtil.exist(save_path)) {
                FileUtil.mkdir(save_path);  // 如果当前文件的父级目录不存在，就创建
                parent_folder_name = mainName;
            } else {
                // 如果当前文件的父级目录存在，说明冲突，需要重命名
                long random = System.currentTimeMillis();
                save_path = save_path + "_" + random;
                parent_folder_name = mainName + "_" + random;
                FileUtil.mkdir(save_path);
            }
            
            File saveFile = new File(save_path + File.separator + originalFilename);
            file.transferTo(saveFile);  // 存储文件到本地的磁盘里面去
            
            // 使用与FileController相同的URL格式，FileController会自动处理SystemPdf路径
            String download_url = "http://" + ip + ":" + port + "/file/download/" + parent_folder_name + "/" + originalFilename;
            String preview_url = "http://" + ip + ":" + port + "/file/preview/" + parent_folder_name + "/" + originalFilename;
            
            // 保存到数据库
            SystemPdf systemPdf = new SystemPdf();
            systemPdf.setName(originalFilename);
            systemPdf.setParentFolderName(parent_folder_name);
            systemPdf.setDownloadUrl(download_url);
            systemPdf.setPreviewUrl(preview_url);
            
            this.save(systemPdf);
            
        } catch (Exception e) {
            throw new RuntimeException("文件上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除物理文件
     */
    private void deletePhysicalFile(String downloadUrl) {
        if (StrUtil.isBlank(downloadUrl)) {
            return;
        }
        
        try {
            // 从下载URL中提取文件路径
            // URL格式: http://localhost:2626/file/download/parentFolderName/fileName
            String[] parts = downloadUrl.split("/file/download/");
            if (parts.length == 2) {
                String filePath = parts[1]; // parentFolderName/fileName
                String fullPath = ROOT_PATH + File.separator + filePath.replace("/", File.separator);
                File file = new File(fullPath);
                if (file.exists()) {
                    file.delete();
                }
                
                // 删除父文件夹（如果为空）
                File parentFolder = file.getParentFile();
                if (parentFolder.exists() && parentFolder.isDirectory() && parentFolder.list().length == 0) {
                    parentFolder.delete();
                }
            }
        } catch (Exception e) {
            // 删除文件失败不影响主流程
            System.err.println("删除物理文件失败: " + e.getMessage());
        }
    }
}
